package com.video.h264;

import java.nio.ByteBuffer;

import android.graphics.Bitmap;

public class BMPImage
{
  private static final int AMPColorMask_SIZE = 12;
  private static final int BITMAPFILEHEADER_SIZE = 14;
  private static final int BITMAPINFOHEADER_SIZE = 40;
  private int bfOffBits;
  private int bfReserved1;
  private int bfReserved2;
  private int bfSize;
  private byte[] bfType;
  private int biBitCount;
  private int biClrImportant;
  private int biClrUsed;
  private int biCompression;
  private int biHeight;
  private int biPlanes;
  private int biSize;
  private int biSizeImage;
  private int biWidth;
  private int biXPelsPerMeter;
  private int biYPelsPerMeter;
  ByteBuffer bmpBuffer;
  private int dwBlue;
  private int dwGreen;
  private int dwRed;

  public BMPImage(byte[] paramArrayOfByte, int dataLen, int paramInt1, int paramInt2)
  {
    byte[] arrayOfByte = { 66, 77 };
    this.bfType = arrayOfByte;
    this.bfSize = 0;
    this.bfReserved1 = 0;
    this.bfReserved2 = 0;
    this.bfOffBits = 66;
    this.biSize = 40;
    this.biWidth = 176;
    this.biHeight = 144;
    this.biPlanes = 1;
    this.biBitCount = 16;
    this.biCompression = 3;
    int i = this.biWidth;
    int j = this.biHeight;
    int k = i * j;
    int m = this.biBitCount >> 3;
    int n = k * m;
    this.biSizeImage = n;
    this.biXPelsPerMeter = 0;
    this.biYPelsPerMeter = 0;
    this.biClrUsed = 0;
    this.biClrImportant = 0;
    this.dwRed = 63488;
    this.dwGreen = 2016;
    this.dwBlue = 31;
    this.bmpBuffer = null;
    this.biWidth = paramInt1;
    this.biHeight = paramInt2;
    int i1 = this.biWidth;
    int i2 = this.biHeight;
    int i3 = i1 * i2;
    int i4 = this.biBitCount >> 3;
    int i5 = i3 * i4;
    this.biSizeImage = i5;
    int i6 = this.biWidth;
    int i7 = this.biHeight;
    int i8 = i6 * i7;
    int i9 = this.biBitCount >> 3;
    int i10 = i8 * i9 + 54 + 12;
    this.bfSize = i10;
    int i11 = this.biWidth;
    int i12 = this.biHeight;
    int i13 = i11 * i12;
    int i14 = this.biBitCount >> 3;
    ByteBuffer localByteBuffer = ByteBuffer.allocate(i13 * i14 + 54 + 12);
    this.bmpBuffer = localByteBuffer;
    writeBitmapFileHeader();
    writeBitmapInfoHeader();
    writeAMPColorMask();
    this.bmpBuffer.put(paramArrayOfByte, 0, dataLen);
  }

  private byte[] intToDWord(int paramInt)
  {
    byte[] arrayOfByte = new byte[4];
    arrayOfByte[0] = (byte)(paramInt & 0xFF);
    arrayOfByte[1] = (byte)(paramInt >> 8 & 0xFF);
    arrayOfByte[2] = (byte)(paramInt >> 16 & 0xFF);
    arrayOfByte[3] = (byte)(paramInt >> 24 & 0xFF);
    return arrayOfByte;
  }

  private byte[] intToWord(int paramInt)
  {
    byte[] arrayOfByte = new byte[2];
    arrayOfByte[0] = (byte)(paramInt & 0xFF);
    arrayOfByte[1] = (byte)(paramInt >> 8 & 0xFF);
    return arrayOfByte;
  }

  private void writeAMPColorMask()
  {
    ByteBuffer localByteBuffer1 = this.bmpBuffer;
    int i = this.dwRed;
    byte[] arrayOfByte1 = intToDWord(i);
    localByteBuffer1.put(arrayOfByte1);
    ByteBuffer localByteBuffer2 = this.bmpBuffer;
    int j = this.dwGreen;
    byte[] arrayOfByte2 = intToDWord(j);
    localByteBuffer2.put(arrayOfByte2);
    ByteBuffer localByteBuffer3 = this.bmpBuffer;
    int k = this.dwBlue;
    byte[] arrayOfByte3 = intToDWord(k);
    localByteBuffer3.put(arrayOfByte3);
  }

  private void writeBitmapFileHeader()
  {
    ByteBuffer localByteBuffer1 = this.bmpBuffer;
    byte[] arrayOfByte1 = this.bfType;
    localByteBuffer1.put(arrayOfByte1);
    ByteBuffer localByteBuffer2 = this.bmpBuffer;
    int i = this.bfSize;
    byte[] arrayOfByte2 = intToDWord(i);
    localByteBuffer2.put(arrayOfByte2);
    ByteBuffer localByteBuffer3 = this.bmpBuffer;
    int j = this.bfReserved1;
    byte[] arrayOfByte3 = intToWord(j);
    localByteBuffer3.put(arrayOfByte3);
    ByteBuffer localByteBuffer4 = this.bmpBuffer;
    int k = this.bfReserved2;
    byte[] arrayOfByte4 = intToWord(k);
    localByteBuffer4.put(arrayOfByte4);
    ByteBuffer localByteBuffer5 = this.bmpBuffer;
    int m = this.bfOffBits;
    byte[] arrayOfByte5 = intToDWord(m);
    localByteBuffer5.put(arrayOfByte5);
  }

  private void writeBitmapInfoHeader()
  {
    ByteBuffer localByteBuffer1 = this.bmpBuffer;
    int i = this.biSize;
    byte[] arrayOfByte1 = intToDWord(i);
    localByteBuffer1.put(arrayOfByte1);
    ByteBuffer localByteBuffer2 = this.bmpBuffer;
    int j = this.biWidth;
    byte[] arrayOfByte2 = intToDWord(j);
    localByteBuffer2.put(arrayOfByte2);
    ByteBuffer localByteBuffer3 = this.bmpBuffer;
	// use negative height to avoid rotate
	int k = -this.biHeight;
    byte[] arrayOfByte3 = intToDWord(k);
    localByteBuffer3.put(arrayOfByte3);
    ByteBuffer localByteBuffer4 = this.bmpBuffer;
    int m = this.biPlanes;
    byte[] arrayOfByte4 = intToWord(m);
    localByteBuffer4.put(arrayOfByte4);
    ByteBuffer localByteBuffer5 = this.bmpBuffer;
    int n = this.biBitCount;
    byte[] arrayOfByte5 = intToWord(n);
    localByteBuffer5.put(arrayOfByte5);
    ByteBuffer localByteBuffer6 = this.bmpBuffer;
    int i1 = this.biCompression;
    byte[] arrayOfByte6 = intToDWord(i1);
    localByteBuffer6.put(arrayOfByte6);
    ByteBuffer localByteBuffer7 = this.bmpBuffer;
    int i2 = this.biSizeImage;
    byte[] arrayOfByte7 = intToDWord(i2);
    localByteBuffer7.put(arrayOfByte7);
    ByteBuffer localByteBuffer8 = this.bmpBuffer;
    int i3 = this.biXPelsPerMeter;
    byte[] arrayOfByte8 = intToDWord(i3);
    localByteBuffer8.put(arrayOfByte8);
    ByteBuffer localByteBuffer9 = this.bmpBuffer;
    int i4 = this.biYPelsPerMeter;
    byte[] arrayOfByte9 = intToDWord(i4);
    localByteBuffer9.put(arrayOfByte9);
    ByteBuffer localByteBuffer10 = this.bmpBuffer;
    int i5 = this.biClrUsed;
    byte[] arrayOfByte10 = intToDWord(i5);
    localByteBuffer10.put(arrayOfByte10);
    ByteBuffer localByteBuffer11 = this.bmpBuffer;
    int i6 = this.biClrImportant;
    byte[] arrayOfByte11 = intToDWord(i6);
    localByteBuffer11.put(arrayOfByte11);
  }

  public byte[] getByte()
  {
    return this.bmpBuffer.array();
  }
  
  public static Bitmap createBitmap565(ByteBuffer rgbBuffer, int frameW, int frameH) {
	  Bitmap target = Bitmap.createBitmap(frameW, frameH, Bitmap.Config.RGB_565);
	  if (null == target)
		  return null;
      target.copyPixelsFromBuffer(rgbBuffer); 
      return target;
  }
  
  public static Bitmap reuseBimtap565(Bitmap candidate, ByteBuffer rgbBuffer, int frameW, int frameH) {
	  Bitmap target = null;
	  if (null == candidate || frameW != candidate.getWidth() || frameH != candidate.getHeight()) {
		  target = createBitmap565(rgbBuffer, frameW, frameH);
	  } else {
		  target = candidate;
		  target.copyPixelsFromBuffer(rgbBuffer);
	  }
	  
	  return target;
  }
}